package com.ysd.twocrm.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ysd.twocrm.entity.Orders;
import com.ysd.twocrm.entity.Permission;
import com.ysd.twocrm.entity.UserRoles;
import com.ysd.twocrm.entity.Users;
import com.ysd.twocrm.mapper.OrdersMapper;
import com.ysd.twocrm.mapper.PermissionMapper;
import com.ysd.twocrm.mapper.UserRolesMapper;
import com.ysd.twocrm.mapper.UsersMapper;
import com.ysd.twocrm.service.UsersService;
import com.ysd.twocrm.token.CheckResult;
import com.ysd.twocrm.token.JwtUtils;
import com.ysd.twocrm.token.SystemConstant;
import com.ysd.twocrm.utils.MD5Utils;
import com.ysd.twocrm.utils.VerifyCode;
import javafx.beans.binding.ObjectExpression;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/users")
public class UsersController {
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private UsersService usersService;
    @Autowired
    private UserRolesMapper userRolesMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private OrdersMapper ordersMapper;


    /*
     * @Description 多条件分页查询    根据用户名查、根据姓名查、创建时间到现在的时间、是否锁定查
     * @param page 分页页码
     * @param u  用户条件
     * @return com.ysd.twocrm.utils.LayuiUtils<com.ysd.twocrm.entity.Users> 返回layui要的格式数据
     * @author liusupeng
     * @date 2020/4/10 17:36
     */
    @GetMapping
    public Object getAllUsers(Integer page, Users u){

        return usersService.USERS_LAYUI_UTILS(page,u);
    }

    /*
     * @Description 查询身份是教员或者辅导员的用户名称（主要用于班级查询、页面显示）
     * @param 教员、辅导员
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/9 16:39
     */
    @GetMapping("/1")
    public Object getAllUserRoles(String roleName){

        return usersMapper.findAllUsers(roleName);
    }

    @GetMapping("/2")
    public Object getAllUserRolesNameById(Integer roleId){

        /*
         * @Description  根据班级内的教员或者辅导员id来查找名字
         * @param roleId
         * @return java.lang.Object
         * @author liusupeng
         * @date 2020/4/9 17:46
         */
        return usersMapper.getAllRoleNameById(roleId);
    }

    /*
     * @Description  根据用户名输入的用户名和密码来进行判断。
     * 如果验证码不对，则登录不进去
     * 如果密码错误次数大于等于5则上锁
     * 如果当前状态是锁定状态也不可进
     * 如果登录进去则修改当前最后一次登录时间
     * @param u 用户信息  validCode：验证码
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/12 15:29
     */
    @GetMapping("/3")
    public Object getAllUserLoginName(Users u,String validCode,HttpSession session){
        Map<String,Object> map=new HashMap<String, Object>();
        Subject subject= SecurityUtils.getSubject();

        String kl = MD5Utils.kl(MD5Utils.password(u.getUserPassword()));//将前台的密码加盐加密然后拿去和后台查询
        UsernamePasswordToken shirotoken=new UsernamePasswordToken(u.getUserLoginName(),kl,true);//将前台发送的用户名和密码存到shiro

        String adminValidCode=(String)session.getAttribute("validCode");//后台验证码
        //将前台和后台的验证码大小写互转做判断，这时不管前台输入大写还是小写都可以
        if(validCode.toLowerCase().equals(adminValidCode.toLowerCase()) || validCode.toUpperCase().equals(adminValidCode.toUpperCase())){
            try {

                subject.login(shirotoken);//操作主体
                Users users = (Users)SecurityUtils.getSubject().getPrincipal();
                if(users.getUserIsLockOut()==0){
                    if(users.getUserpsdWrongSum()>=5&&users.getIsUserRoleId()!=0){
                        //上锁
                        usersMapper.exituserIsLockOut(users.getUserId(),1);
                        map.put("falseislockOut","falseislockOut");
                        return map;
                    }else{
                        //登录成功,修改当前最后一次登录时间
                        usersMapper.exitUsersLastLoginTime(users.getUserId());
                        //查询用户拥有权限
                        List<String> slist=new ArrayList<>();
                        List<Permission> permissionList = permissionMapper.PERMISSION_LIST(users.getUserId());
                        for(int i=0;i<permissionList.size();i++){
                            slist.add(permissionList.get(i).getPermissionValue());
                        }
                        String jwt= JwtUtils.createJWT(String.valueOf(users.getUserId()),users.getUserName(), SystemConstant.JWT_TTL);

                        map.put("permission",slist);
                        map.put("success","success");
                        map.put("user",users);
                        map.put("jwt",jwt);
                        return map;
                    }
                }else{
                    //已经上锁
                    map.put("falseislockOut","falseislockOut");
                    return map;
                }
            }catch (UnknownAccountException e){
                //用户名错误
                map.put("falseloginname","false");
                return map;
            }catch (IncorrectCredentialsException e){
                //密码错误，如果账户没有错的话则对他修改密码错误次数
                usersMapper.exitusersPwdByloginName(u.getUserLoginName());
                map.put("falsepassword","false");
                return map;
            }

        }else{
            map.put("validCodefalse","validCodefalse");
            return map;
        }



    }
//验证码
@GetMapping("/4")
    public Object getVerifyCode(HttpServletResponse response, HttpServletRequest request){
        HttpSession session=request.getSession();
    String validCode = VerifyCode.getValidCode(response);//图片通过response响应出去
    session.setAttribute("validCode",validCode);

    return null;
    }
    //多条件根据用户id来修改个人信息以及密码
    @GetMapping("/5")
    public Object getAllUserMessage(Integer userId){
        Users allUsersById = usersService.getAllUsersById(userId);
        return allUsersById;
    }
    /*
     * @Description 注册时验证，登录名和手机号是否存在，如果存在则返回提示，不存在也返回
     * @param phone
     * @param loginName
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/13 22:29
     */
    @GetMapping("/6")
    public String getIfPhoneByName(String phone,String loginName,String code,HttpSession session){
        //首先判断发送的验证码
        System.out.println(code+"<==验证码");
      //  if(!session.getAttribute("ssmCode").equals(code)){
        if(!"123456".equals(code)){
            return "falsecode";
        }
        Users userLoginName = usersMapper.findUserLoginName(loginName);
        Users userPhone = usersMapper.findUserPhone(phone);
        if(userLoginName==null){
             if(userPhone==null){
                 return "success";
             }else{
                 return "phonefalse";
             }
        }else{
            return "loginFalse";
        }

    }
    /*
     * @Description 根据发送的手机号来后台判断是否存在，如果存在则返回success
     * 并通过session来将手机号存起来用于修改密码
     * @param usersPhone 手机号
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/13 22:31
     */
    @GetMapping("/7")
    public String getIfOhone(String cellphone,HttpSession session,String vercode){
         //首先发送的验证码
            if(!session.getAttribute("ssmCode").equals(vercode)){
                return "falsecode";
            }
        Users userPhone = usersMapper.findUserPhone(cellphone);
        if(userPhone!=null){
            session.setAttribute("cellphone",cellphone);
            return "success";
        }
        return "false";
    }
    /*
     * @Description 用来判断是否自动分配，查询了第一条用户的信息，当然这个随意
     * 如果为0则返回给咨询经理的那个开关按钮
     * @param
     * @return java.lang.Integer
     * @author liusupeng
     * @date 2020/4/14 8:42
     */
    @GetMapping("/8")
    public Integer getAllUserListExit1(){


        Users usersExit1 = usersMapper.findUsersExit1();

        return usersExit1.getExit1();
    }
    /*
     * @Description 查询全部咨询师或者游客的身份，并且带有名字模糊查询
     * @param page 分页页码
     * @param roleName 身份
     * @param u 用户姓名
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/14 10:09
     */
    @GetMapping("/9")
    public Object getAllUsersConselor(Integer page,String roleName,String userName ){
                  if(userName==null){
                      userName="";
                  }
      return   usersService.findLayuiUtils(page,userName,roleName);
    }
@GetMapping("/10")
    public Object getAllUserRolesWeight(Integer userId,String roleName){
        /*
         * @Description  根据用户id和角色名来查询用户角色信息，主要用于咨询师来查询权重值
         * @param userId
        	 * @param roleName
         * @return java.lang.Object
         * @author liusupeng
         * @date 2020/4/14 10:52
         */
        return userRolesMapper.findWeight(userId,roleName);
    }
    /*
     * @Description 多条件查询当前咨询师下的所有用户
     * @param page
     * @param u
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/14 19:41
     */

    @GetMapping("/11")
    public Object getAllUsersConsulogs(Integer page,Users u){

        return usersService.layuiCounselor(page,u);
    }
    /*
     * @Description 首先获取前台传来的token，然后在通过session读取到登录时获取的token，
     * 然后先验证前台传来的token是否有效，如果有效则跟后台登录时session存的token来比较，如果一样，就返回success
     * @param token
     * @param session
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/12 20:31
     */
    @GetMapping("/12")
    public Object getIfLoginToken(String token){

        CheckResult checkResult = JwtUtils.validateJWT(token);
        if(checkResult.isSuccess()){
            //代表当前token还ok
                 return "success";
        }
        return "false";
    }
    /*
     * @Description 根据用户id和咨询师来查询当前咨询师的权重值
     * @param userId
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/14 16:26
     */
    @GetMapping("/13")
    public Object getAllWeightByUserId(Integer userId){


        return userRolesMapper.findWeight(userId,"咨询师");
    }
    /*
     * @Description 根据用户id来锁定账户，或者解锁账户  当解锁的时候将当前用户的错误次数修改为0
     * @param userIsLockOut
     * @param userId
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/10 18:46
     */
    @PutMapping
    public String getExituserIsLockOut(Integer userIsLockOut,Integer userId){
              if(userIsLockOut==0){
                  //解锁时候将锁定时间设置null
                  usersMapper.exituserIsLockOutTime(userId,"null");
                  usersMapper.exitusersPwdIdById(userId);//当解锁的时候将当前用户的错误次数修改为0
              }else{
                  //上锁时候修改为锁定的当前时间 now() 是数据库的当前时间
                  usersMapper.exituserIsLockOutTime(userId,"now()");
              }
        Integer integer = usersMapper.exituserIsLockOut(userId, userIsLockOut);

        System.out.println(integer);
        if(integer>0){
            return "success";
        }
        return "false";
    }
    /*
     * @Description 修改个人信息
     * 这里先通过用户去获取当前用户的密码然后去和前台传来的进行比较，如果一样的话就说明用户没有换密码，就不用转换md5了因为上面给他渲染的本身他就是加密后的
     * 如果说密码换了那就需要将他的密码给他加盐加密就行
     * @param u
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/5/11 18:02
     */
    @PutMapping("/1")
    public String exitUserMessage(Users u){

        Users allUsersById = usersService.getAllUsersById(u.getUserId());
        if(!u.getUserPassword().equals(allUsersById.getUserPassword())){
            u.setUserPassword(MD5Utils.kl( MD5Utils.password(u.getUserPassword())));//将密码加盐加密
        }

    try {
        Integer integer = usersService.exitUserMessage(u);
        if(integer>=0){
            return "success";
        }
        return "false";
    }catch (Exception e){
        return "sqlfalse";
    }
    }
    //根据手机号来修改密码
    @PutMapping("/2")
    public String exitUsersPwdByPhone(String userPassword,HttpSession session){
        String cellphone = (String)session.getAttribute("cellphone");
               //将密码加盐加密
        Integer integer = usersMapper.exitUsersPwdByPhone(MD5Utils.kl(MD5Utils.password(userPassword)), cellphone);
        if(integer>0){
            return "success";
        }
        return "false";
    }
    /*
     * @Description  是否开启自动分配咨询师
     * @param exit1 0：开启 1：不开启
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/14 8:23
     */
    @PutMapping("/3")
    public Object exitusersExit1Auto(Integer exit1){

        return usersMapper.exitUserExit1(exit1);
    }
    /*
     * @Description 根据用户角色id和权重值来为当前用户角色修改权重值（用于咨询师）
     * @param userRolesWeight
     * @param userRolesId
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/14 14:54
     */
    @PutMapping("/4")
    public String exitUserRolesWeight(Integer userRolesWeight,Integer userRolesId){

        Integer integer = userRolesMapper.exitWeight(userRolesId, userRolesWeight);
        if(integer>0){
            return "success";
        }
        return "false";
    }
    @PutMapping("/5")
    public String exitUsersConsoler(Integer userId,Integer isCounselor){
        Integer integer = usersMapper.exitUsersConsoler(userId, isCounselor);
        if(integer>0){
            return "success";
        }
        return "false";
    }
    /*
     * @Description 批量修改咨询师
     * @param str
     * @param IsCounselor
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/26 11:05
     */
@PutMapping("/6")
    public Object exitConsoler(String str,Integer IsCounselor){

    String[] split = str.split(",");
       QueryWrapper<Users> queryWrapper=new QueryWrapper<Users>();
       queryWrapper.in("userId",split);
       Users u=new Users();
       u.setIsCounselor(IsCounselor);
    int update = usersMapper.update(u, queryWrapper);
    if(update>0){
        return "success";
    }
    return false;
    }
    /*
     * @Description 一键自动分配咨询师
     * @param
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/26 11:06
     */
    @PutMapping("/7")
    public Object exitAuto(){
          SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        List<Users> youke = usersMapper.findAllUsers("游客");

            for(int i=0;i<youke.size();i++){
                if(youke.get(i).getIsCounselor()!=null && youke.get(i).getIsCounselor()!=0){

                }else{
                    Integer ranid = usersService.randomCounselor(sdf.format(new Date()));
                    if(ranid==null){
                        return "false";
                    }
                    Users u=new Users();
                    u.setIsCounselor(ranid);
                    u.setUserId(youke.get(i).getUserId());
                    usersMapper.updateById(u);
                    //执行自动分配

                }

            }

        return "success";
    }

    /*
     * @Description 添加用户，并且为当前用户设置游客的身份
     * 判断：如果查询的第一个用户的是否自动分配为0：则自动分配，则为他添加咨询师的用户
     * 先判断如果是自动分配，则去查询当前已经上线的咨询师，如果没有任何上线的咨询师，则关闭自动分配
     * @param u
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/4/14 8:56
     */
    @PostMapping
    public String addUsers(Users u,HttpSession session,String code){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String time=sdf.format(new Date());
        Users usersExit1 = usersMapper.findUsersExit1();//判断是否开启了自动分配
        if(usersExit1!=null && usersExit1.getExit1()==0){
            Integer randomCounselor = usersService.randomCounselor(time);
            if(randomCounselor!=null){
              u.setIsCounselor(randomCounselor);
          }else{
                usersMapper.exitUserExit1(1);//关闭自动分配按钮
                u.setIsCounselor(0);
            }
        }
        u.setUserIsLockOut(0);
        u.setUserCreateTime(new Date());
        u.setUserpsdWrongSum(0);
         u.setIsUserRoleId(3);//代表游客
        //将密码加盐加密
        u.setUserPassword(MD5Utils.kl(MD5Utils.password(u.getUserPassword())));
        int insert = usersMapper.insert(u);
        //查找游客身份的角色id
        Integer ykId = userRolesMapper.getAllRoleNameById("游客");
        UserRoles ur=new UserRoles(0,ykId,u.getUserId(),0,0);

                if(insert>0){
                    userRolesMapper.insert(ur);
                     return "success";
                 }

        return "false";
    }

    /*
     * @Description 这个主要用来删除用户的时候并且删除当前用户的角色
     * 还有一个用处是在添加学生的时候会判断是不是游客变成学生，
     * 如如果是的话则先将当前用户的咨询师给他的权重值+1
     * @param userId
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/4/14 21:03
     */
    @DeleteMapping
    public Object delUsers(Integer userId){
        QueryWrapper<Users> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("userId",userId);
        Users users = usersMapper.selectOne(queryWrapper);
        if(users!=null){
      userRolesMapper.updateWeightByUserId(users.getIsCounselor());
        }
        userRolesMapper.delUsersRole(userId);
        return usersMapper.deleteById(userId);
    }
    /*
     * @Description 先根据游客id去查当前游客是否已经付过款，如果付过款的话则返回success 没有付款则调用上面的删除方法。
     * @param userId
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/15 8:11
     */
    @DeleteMapping("/1")
    public Object delUsersByOrders(Integer userId){

        Orders orders = ordersMapper.selectOrdersByUserId(userId);
        if(orders==null){

            delUsers(userId);
            return "false";

        }

        return "success";
    }
    /*
     * @Description  如果没有权限就跳转到这个方法，这个方法在返回到前台的一个页面，用于提示没有权限的
     * @param response
     * @return void
     * @author liusupeng
     * @date 2020/5/7 14:40
     */
    @GetMapping("/permissionLogOut")
    public void getLog(HttpServletResponse response,HttpServletRequest request) throws IOException {
        String loginPath="http://127.0.0.1:8848/twocrm/src/views/template/tips/perssionErrror.html";
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        boolean isAjaxRequest = false;
        if (!StringUtils.isBlank(request.getHeader("Accept")) && request.getHeader("Accept").equals("application/json, text/javascript, */*; q=0.01")) {
            isAjaxRequest = true;
        }
        if(isAjaxRequest){
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSONObject.toJSON("您没有访问这个操作的权限!").toString());
            response.setStatus(403);
            response.setHeader("REDIRECT", "REDIRECT");//告诉ajax这是重定向  
            response.setHeader("CONTEXTPATH", loginPath);//重定向地址  
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        }else{
            response.sendRedirect(loginPath);
        }

    }
    @GetMapping("/getgologin")
    public void getLogin(HttpServletResponse response,HttpServletRequest request) throws IOException {
        String loginPath = "http://127.0.0.1:8848/twocrm/src/views/user/login.html";
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        boolean isAjaxRequest = false;
        if (!StringUtils.isBlank(request.getHeader("Accept")) && request.getHeader("Accept").equals("application/json, text/javascript, */*; q=0.01")) {
            isAjaxRequest = true;
        }
        if(isAjaxRequest){
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSONObject.toJSON("登录认证失效，请重新登录!").toString());
            response.setStatus(403);
            response.setHeader("REDIRECT", "REDIRECT");//告诉ajax这是重定向  
            response.setHeader("CONTEXTPATH", loginPath);//重定向地址  
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        }else{
            response.sendRedirect(loginPath);
        }

    }
    /*
     * @Description 退出当前信息，先清空session然后退出shiro
     * 先去判断当前有没有在线的咨询师，如果有的话则无视，没有的话则修改成关闭自动分配
     * @param session
     * @return java.lang.Object
     * @author liusupeng
     * @date 2020/5/7 8:56
     */
    @GetMapping("/goout")
    public Object goout(HttpSession session){

        session.invalidate();//清空全部session
        Subject subject=SecurityUtils.getSubject();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String time=sdf.format(new Date());
        List<UserRoles> userRoles = userRolesMapper.USER_ROLES(time);
        if(userRoles.isEmpty()){
            usersMapper.exitUserExit1(1);//关闭自动分配按钮
        }
        try {
            subject.logout();
        }catch (Exception e){

        }
        return "success";
    }


}
